package util;

import java.io.BufferedReader;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;


import data.*;
import java.util.*;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

/**
 * Servlet implementation class DoMashup
 */
public class WineRequester{

    public static String numResult="1";

    public static void getWineData(ArrayList<RecipeData> recipes){
        
        ExecutorService es = Executors.newFixedThreadPool(50);
        @SuppressWarnings("rawtypes")
		List<Future> futures = new ArrayList<Future>();
        for(int i=0;i<recipes.size();i++) {
          final RecipeData recipe= recipes.get( i );
          for(int j=0; j<3;j++){
              final Varietal recVarietal= recipe.getVarietals().get( j );
              futures.add(es.submit(new Runnable() {
                @Override
                public void run() {
                    try {
                        WineData wine= getWineData(recVarietal);
                        if(wine.getName()!=null){
                            recipe.addWine(wine  );
                        }
                        
                    } catch( IOException e ) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
              }));
          }
       
        }
        for (@SuppressWarnings("rawtypes") Future future:futures)
            try {
                future.get();  // blocking call, explicitly waiting for the response from a specific task, not necessarily the first task that is completed
            } catch (InterruptedException e) {
            } catch (ExecutionException e) {
            }
    }
//public static void getWineData(ArrayList<RecipeData> recipes) throws IOException{
//        
//        
//        for(int i=0;i<recipes.size();i++) {
//          RecipeData recipe= recipes.get( i );
//          for(int j=0; j<recipe.getVarietals().size();j++){
//              Varietal recVarietal= recipe.getVarietals().get( j );
//              System.out.println("Requesting wine for varietal: " + recVarietal.name()+ " type: "+recVarietal.getType());
//                        WineData wine= getWineData(recVarietal);
//                        if(wine.getName()!=null){
//                            recipe.addWine(wine  );
//                            System.out.println("Added wine for varietal "+recVarietal.name()+ " type: "+recVarietal.getType());
//                            System.out.println(recipe.getWines().size());   
//                        }else{
//                            System.out.println("NO wine for varietal "+recVarietal.name()+ " type: "+recVarietal.getType());
//                        }
//                        
//                 
//          }
//       
//        }
//
//    }



    public static WineData getWineData(Varietal recVarietal) throws IOException{
        //setup http request for snooth
        String varietal = recVarietal.getVarietal();
        String type= recVarietal.getType();
        varietal =varietal.replace(" ", "+");
        type= type.replace(" ", "+");
        URL wineRequest = new URL("http://api.snooth.com/wines/?akey=g699zqxot7lsmmqrzy8x1fr7aaki9pcck28umj1wp7uidaoe&n="+numResult+"&q=" + varietal + "+" +type + "&format=xml");
        URLConnection wineConnect = wineRequest.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(wineConnect.getInputStream()));
        in.readLine();//first line, xml version
        String inputLine=in.readLine(); //second line, starts with <snooth>
        in.close();

        //get wine
        WineData wine = new WineData();
        Node currN;
        Element currE;
        NodeList snoothElems;
        NodeList winesElems;
        NodeList tmpNL;
        Element tmpE;
        try{
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            Document doc = db.parse(new InputSource(new ByteArrayInputStream(inputLine.getBytes("utf-8"))));
            doc.getDocumentElement().normalize();

            snoothElems = doc.getDocumentElement().getChildNodes();
            for(int i = 0; i < snoothElems.getLength(); i++){
                currN = snoothElems.item(i);
                if(currN.getNodeType() != Node.ELEMENT_NODE)
                    continue;

                currE = (Element)currN;

                if(currE.getNodeName().equalsIgnoreCase("wines")){
                    winesElems= currE.getChildNodes();
                    for(int x=0;x<Integer.parseInt( numResult );x++){
                        tmpNL =winesElems.item( x ).getChildNodes();
                        for(int j = 0; j < tmpNL.getLength(); j++){
                            tmpE = (Element)tmpNL.item(j);
                            if(tmpE.getNodeName().equalsIgnoreCase("name")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setName( tmpE.getFirstChild().getNodeValue() );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("link")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setUrl( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("snoothrank")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setRating( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("type")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setDescrip( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("price")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setPrice( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("winery")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setWinery( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("varietal")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setVarietal( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("region")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setRegion( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("vintage")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setVintage( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                            if(tmpE.getNodeName().equalsIgnoreCase("image")){
                                if(tmpE.getChildNodes().getLength()>0){
                                wine.setImageURL( tmpE.getFirstChild().getNodeValue()  );
                                }
                            }
                        }
                    }
                }


            }
        }catch(Exception e){}
        return wine;
    }



}
